#include "precomp.h"
#include "inffile.h"
#include "params.h"
#include "devutils.h"
#include "msg.h"
#include "utils.h"
#include "portnum.h"
#include "comdb.h"
#include <msports.h>

#define TEXT_PREF
#include "../include/com0com.h"
#include "iot.h"

#define C0C_INF_NAME             "com0com.inf"
#define C0C_INF_NAME_CNCPORT     "cncport.inf"
#define C0C_INF_NAME_COMPORT     "comport.inf"
#define C0C_CNCCLASS_GUID        "{df799e12-3c56-421b-b298-b6d3642bc878}"
#define C0C_COMCLASS_GUID        "{4d36e978-e325-11ce-bfc1-08002be10318}"
#define C0C_PROVIDER             "Vyacheslav Frolov"
#define C0C_REGKEY_EVENTLOG      REGSTR_PATH_SERVICES "\\Eventlog\\System\\" C0C_SERVICE
#define C0C_COPY_DRIVERS_SECTION "com0com_CopyDrivers"

#define C0C_SETUP_TITLE          "Setup for com0com"
///////////////////////////////////////////////////////////////
static const InfFile::InfFileField requiredFieldsInfBusInstall[] = {
	{ "Version",         "ClassGUID",          1, C0C_CNCCLASS_GUID },
	{ "Version",         "Provider",           1, C0C_PROVIDER },
	{ "Version",         "UninstallInfTag",    1, C0C_CNCCLASS_GUID },
	{ "Manufacturer",    NULL,                 1, C0C_SERVICE },
	{ NULL },
};

static const InfFile::InfFileField requiredFieldsInfCNCPortInstall[] = {
	{ "Version",         "ClassGUID",          1, C0C_CNCCLASS_GUID },
	{ "Version",         "Provider",           1, C0C_PROVIDER },
	{ "Version",         "UninstallInfTag",    1, C0C_CNCCLASS_GUID },
	{ "Manufacturer",    NULL,                 1, C0C_SERVICE },
	{ NULL },
};

static const InfFile::InfFileField requiredFieldsInfCOMPortInstall[] = {
	{ "Version",         "ClassGUID",          1, C0C_COMCLASS_GUID },
	{ "Version",         "Provider",           1, C0C_PROVIDER },
	{ "Version",         "UninstallInfTag",    1, C0C_CNCCLASS_GUID },
	{ "Manufacturer",    NULL,                 1, C0C_SERVICE },
	{ NULL },
};

struct InfFileInstall {
	const char *pInfName;
	const char *pCopyDriversSection;
	const char *pHardwareId;
	bool preinstallClass;
	const InfFile::InfFileField *pRequiredFields;
};

static const InfFileInstall infFileInstallList[] = {
	{ C0C_INF_NAME,          C0C_COPY_DRIVERS_SECTION,  C0C_BUS_DEVICE_ID,        TRUE,  requiredFieldsInfBusInstall },
	{ C0C_INF_NAME_CNCPORT,  NULL,                      C0C_PORT_HW_ID_CNCCLASS,  FALSE, requiredFieldsInfCNCPortInstall },
	{ C0C_INF_NAME_COMPORT,  NULL,                      C0C_PORT_HW_ID_COMCLASS,  FALSE, requiredFieldsInfCOMPortInstall },
	{ NULL },
};
///////////////////////////////////////////////////////////////
static const InfFile::InfFileField requiredFieldsInfUnnstallInfTag[] = {
	{ "Version",         "UninstallInfTag",    1, C0C_CNCCLASS_GUID },
	{ "Manufacturer",    NULL,                 1, C0C_SERVICE },
	{ NULL },
};

static const InfFile::InfFileField requiredFieldsInfUnnstallCNCOld[] = {
	{ "Version",         "ClassGUID",          1, C0C_CNCCLASS_GUID },
	{ "Version",         "Provider",           1, C0C_PROVIDER },
	{ "Version",         "CatalogFile",        1, "com0com.cat" },
	{ NULL },
};

static const InfFile::InfFileField requiredFieldsInfUnnstallCNCClass[] = {
	{ "Version",         "ClassGUID",          1, C0C_CNCCLASS_GUID },
	{ NULL },
};

static const InfFile::InfFileField requiredFieldsInfUnnstallCOMClass[] = {
	{ "Version",         "ClassGUID",          1, C0C_COMCLASS_GUID },
	{ "Manufacturer",    NULL,                 1, C0C_SERVICE },
	{ NULL },
};

static const InfFile::InfFileUninstall infFileUnnstallList[] = {
	{ requiredFieldsInfUnnstallInfTag,    FALSE },
	{ requiredFieldsInfUnnstallCNCOld,    FALSE },
	{ requiredFieldsInfUnnstallCNCClass,  TRUE },
	{ requiredFieldsInfUnnstallCOMClass,  TRUE },
	{ NULL },
};
///////////////////////////////////////////////////////////////
static int timeout = 0;
static bool repeate_timeout = FALSE;
static bool detailPrms = FALSE;
static bool no_update = FALSE;
static bool no_update_fnames = FALSE;
static bool show_fnames = FALSE;
///////////////////////////////////////////////////////////////
void VSPM_Init()
{
	timeout = 0;
	repeate_timeout = FALSE;
	detailPrms = FALSE;
	no_update = FALSE;
	no_update_fnames = FALSE;
	show_fnames = FALSE;

	if (!SetOutputFile(NULL))
		return ;

	Silent(FALSE);

	extern void Help(const char *pProgName);

	Help("Program Name");
}

///////////////////////////////////////////////////////////////
int VSPM_Complete(bool ok)
{
	if (ok) {
		if (timeout > 0)
			WaitNoPendingInstallEvents(timeout, repeate_timeout);

		return 0;
	}

	return 1;
}
///////////////////////////////////////////////////////////////
bool VSPM_Change(const char *pPhPortName, const char *pParameters)
{
	return VSPM_Complete(Change(pPhPortName, pParameters));
}

bool VSPM_Install(const char *pInfFilePath, const char *pParametersA, const char *pParametersB, int num)
{
	return VSPM_Complete(Install(pInfFilePath, pParametersA, pParametersB, num));
}